
function CaseItem(tree, name, action) {
    this.tree = tree;
    this.name = name;
    this.action = action;
    this.subnodes = [];
    this.rates = [];
}

CaseItem.prototype.getTree = function () {
    return this.tree;
};

CaseItem.prototype.getName = function () {
    return this.name;
};

CaseItem.prototype.doAction = function (data) {
    this.action(data);
}

CaseItem.prototype.random = function () {
    if (subnodes.length == 0) return null;
    var total = 0;
    for (var i in subnodes) {
        total += rates[i];
    }
    var x = total * Math.random();
    total = 0;
    for (var i in subnodes) {
        total += rates[i];
        if (x <= total) return subnodes[i];
    }
    return null;
}

CaseItem.prototype.hasSubNode = function () {
    return subnodes.length > 0;
}

CaseItem.prototype.addSubNode = function(name, rate) {
    if (this.subnodes.hasOwnProperty(name)) {
        throw name + ' subnode already existed in. [' + this.name + ']';
    }
    if (typeof (rate) != 'number') {
        throw 'type of rate master be use number';
    }
    if (rate <= 0) {
        throw 'rate must greater than zero';
    }
    var subnode = tree.getNode(subnode);
    this.subnodes[name] = tree.getNode(name);
    this.rates[name] = rate;
}

function CaseTree() {
    this.nodes = [];
    this.root = null;
}

CaseTree.prototype.addNode = function (name, action) {
    if (typeof (name) != 'string') {
        throw 'CaseItem\'s name invalid type';
    }
    if (this.nodes.hasOwnProperty(name)) {
        throw 'node already existed. [' + name + ']';
    }
    this.nodes[name] = new CaseItem(this, name, action);
    if (this.root == null) this.root = this.nodes[name];
}

CaseTree.prototype.addSubNode = function (name, subname, rate) {
    if (this.nodes.hasOwnProperty(name)) {
        throw 'node not already existed. [' + name + ']';
    }
    node = nodes[name];
    node.addSubNode(subnode, rate);
}

CaseTree.prototype.getNode = function (name) {
    if (!this.nodes.hasOwnProperty(name)) {
        throw 'node not already existed. [' + name + ']';
    }
    return this.nodes[name];
}

CaseTree.prototype.setRoot = function (name) {
    this.root = this.getNode(name);
}

CaseTree.prototype.getRoot = function () {
    return this.root;
}

exports.create = function () {
    return new CaseTree();
}
